package com.xiaodeng.xdblogspringboot.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import com.xiaodeng.xdblogspringboot.interceptors.LoginInterceptor;
import com.xiaodeng.xdblogspringboot.pojo.Article;
import com.xiaodeng.xdblogspringboot.pojo.DTO.UserDTO;
import com.xiaodeng.xdblogspringboot.pojo.PageBean;
import com.xiaodeng.xdblogspringboot.pojo.Result;
import com.xiaodeng.xdblogspringboot.pojo.User;
import com.xiaodeng.xdblogspringboot.service.UserService;
import com.xiaodeng.xdblogspringboot.utils.ThreadLocalUtil;
import jakarta.validation.constraints.Pattern;
import org.hibernate.validator.constraints.URL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.xiaodeng.xdblogspringboot.constant.RedisConstants.USER_TOKEN;
import static com.xiaodeng.xdblogspringboot.constant.RedisConstants.VERIFICATION_CODE;


@Validated
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;



    // 用户注册
    @PostMapping("/register")
    public Result register(@Pattern(regexp = "^[a-zA-Z0-9_.*]{6,16}$",message = "账号仅支持6到16位的数字、字母、‘_’、‘.’和‘*’！") String username,
                           @Pattern(regexp = "^[a-zA-Z0-9_.*]{6,16}$",message = "密码仅支持6到16位的数字、字母、‘_’、‘.’和‘*’！") String password,
                           @RequestParam String verificationCode,@RequestParam String email) {
        // 从 Redis 中获取验证码
        String redisKey = VERIFICATION_CODE + email;
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        String storedCode = operations.get(redisKey);
        System.out.println(storedCode);
        // 验证验证码
        if (storedCode == null || !storedCode.equals(verificationCode)) {
            return Result.error("验证码无效或已过期");
        }
        // 如果验证码有效，进行注册
        userService.register(username, password,email);
        // 注册成功后，删除验证码
        stringRedisTemplate.delete(redisKey);
        return Result.success("注册成功");
    }

    //用户登录
    @PostMapping ("/login")
    public Result<String> login(@Validated String username,String password) {
        String token = userService.login(username, password);
        // 使用用户名作为键来存储 token
        String userKey = USER_TOKEN + username;
        // 检查是否已有 token
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        String oldToken = operations.get(userKey);
        if (oldToken != null) {
            // 使用 userKey 删除旧的 token
            stringRedisTemplate.delete(userKey);
        }
        // 存储新的 token
        operations.set(userKey, token, 4, TimeUnit.DAYS);
        return Result.success("登陆成功",token);
    }
    // 用户登出
    @LoginInterceptor.GlobalJwtIntercept
    @PostMapping("/logout")
    public Result logout() {
        Map<String,Object> map = ThreadLocalUtil.get();
        Object username = map.get("username");
        String userKey = USER_TOKEN + username;
        // 从 Redis 中删除 token
        stringRedisTemplate.delete(userKey);
        return Result.success("登出成功");
    }
    @LoginInterceptor.GlobalJwtIntercept
    //用户注销 TODO 应该将自己的文章这些也删除
    @DeleteMapping("/delete")
    public Result delete(Integer id){
        userService.delete(id);
        return Result.success("注销成功");
    }

    //用户修改信息
    @LoginInterceptor.GlobalJwtIntercept
    @PatchMapping  ("/update")
    public Result update(@Validated @RequestBody User user){
        userService.update(user);
        return Result.success("修改成功");
    }
    @LoginInterceptor.GlobalJwtIntercept
    //更新用户头像
    @PatchMapping("/updateAvatar")
    public Result updateAvatar(@RequestParam @URL String avatarUrl){
        userService.updateAvatar(avatarUrl);
        return Result.success();
    }
    @LoginInterceptor.GlobalJwtIntercept
    //用户修改密码
    @PatchMapping("/updatePwd")
    public Result updatePwd(@RequestBody @Validated UserDTO userDTO, @RequestHeader("Authorization") String token){
        User user = BeanUtil.copyProperties(userDTO,User.class);
        System.out.println(user.getPassword());
        String newPwd = userDTO.getNewPwd();
        userService.updatePwd(newPwd,user);
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        operations.getOperations().delete(token);
        return Result.success("修改成功");
    }
    //查询用户信息
    @LoginInterceptor.GlobalJwtIntercept
    @GetMapping("/userInfo")
    public Result<User> userInfo(){
        //根据用户名查询用户
        Map<String,Object> map = ThreadLocalUtil.get();
        String username =(String) map.get("username");
        System.out.println(username);
        User user = userService.findByUserName(username);
        return Result.success(user);
    }

    //查询自己写的博客
    @LoginInterceptor.GlobalJwtIntercept
    @GetMapping("/getArticle")
    public Result<PageBean<Article>> getArticle(Integer pageNum,
                                                Integer pageSize){
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer userId =(Integer) map.get("id");
        PageBean<Article> pb = userService.getArticle(pageNum,pageSize,userId);
        return Result.success(pb);
    }

    //发送验证码
    @GetMapping("/verificationCode")
    public Result<Object> sendVerificationCode(@RequestParam @Validated String email) {
        // 生成六位数字验证码
        String verificationCode = RandomUtil.randomNumbers(6);
        // 发送验证码到用户邮箱
        userService.sendEmail(email, verificationCode);
        // 将验证码存储到 Redis，设置有效期为 5 分钟
        stringRedisTemplate.opsForValue().set(VERIFICATION_CODE + email, verificationCode, 5, TimeUnit.MINUTES);
        return Result.success("验证码发送成功！", null);
    }
    /**
     * 查询当月新注册用户数量
     * @return 包含当月新注册用户数量的结果对象
     */
    @GetMapping("/countNewUsersThisMonth")
    public Result<Integer> countNewUsersThisMonth() {
        Date currentDate = new Date();
        int count = userService.countNewUsersThisMonth(currentDate);
        return Result.success("查询成功", count);
    }

}

